package com.unitd.frame.sso.common.encrypt;

import com.unitd.frame.sso.common.config.SSOConfig;
import com.unitd.frame.comm.utils.ByteUtils;
import com.unitd.frame.comm.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.security.MessageDigest;

/**
 * @desc 盐值加密工具类（常用登录密码加密）
 * @filename Salt.java
 * @copyright www.pactera.com.cn
 * @author Hudan
 * @version 1.0
 * @date 2016/10/27
 */
public class Salt {

	private static final Logger logger = LoggerFactory.getLogger(Salt.class.getName());

	/** 盐值 */
	private String salt;
	/** 加密算法 */
	private String algorithm;

	protected Salt() {
		/* 保护 */
	}

	public Salt(String salt, String algorithm) {
		this.salt = salt;
		this.algorithm = algorithm;
	}

	/**
	 * @desc MD5将需要加密的字符串根据盐值和默认的算法进行加密, 得到最终的盐值加密字符串
	 * @param salt    盐值
	 * @param rawText 需要加密的字符串
	 * @return 盐值加密字符串
	 */
	public static String md5SaltEncode(String salt, String rawText) {
		return new Salt(salt, MD5.ALGORITHM).encode(rawText);
	}

	/**
	 * @desc 判断MD5盐值加密内容是否正确
	 * @param salt       盐值
	 * @param encodeText 加密后的文本内容
	 * @param rawText    加密前的文本内容
	 * @return 验证结果, 正确返回true, 否则返回false
	 */
	public static boolean md5SaltValid(String salt, String encodeText, String rawText) {
		return new Salt(salt, MD5.ALGORITHM).isValid(encodeText, rawText);
	}

	/**
	 * @desc 字符串盐值加密
	 * @param rawText 需要加密的字符串
	 * @return 盐值加密字符串
	 */
	public String encode(String rawText) {
		try {
			MessageDigest md = MessageDigest.getInstance(algorithm);
			// 加密后的字符串
			return ByteUtils.byte2Hex(md.digest(mergeRawTextAndSalt(rawText).getBytes(SSOConfig.getSSOEncoding())));
		} catch (Exception e) {
			logger.error("字符串盐值加密失败:" + e);
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * @desc 判断加密内容是否正确
	 * @param encodeText 加密后的文本内容
	 * @param rawText    加密前的文本内容
	 * @return 验证结果, 正确返回true, 否则返回false
	 */
	public boolean isValid(String encodeText, String rawText) {
		return this.encode(rawText).equals(encodeText);
	}

	/**
	 * @desc 合并混淆盐值至加密内容
	 * @param rawText 需要加密的字符串
	 * @return 合并后的盐值加密内容
	 */
	private String mergeRawTextAndSalt(String rawText) {
		if (StringUtils.isBlank(rawText)) {
			rawText = "";
		}

		if (StringUtils.isBlank(this.salt)) {
			return rawText;
		} else {
			StringBuilder sb = new StringBuilder();
			sb.append(rawText);
			sb.append(SSOConfig.CUT_SYMBOL);
			sb.append(this.salt);
			return sb.toString();
		}
	}

	public String getSalt() {
		return salt;
	}

	public void setSalt(String salt) {
		this.salt = salt;
	}

	public String getAlgorithm() {
		return algorithm;
	}

	public void setAlgorithm(String algorithm) {
		this.algorithm = algorithm;
	}

	public static void main(String[] args) {
		System.out.println(md5SaltEncode("admin", "123456"));
	}
}